package il.ac.tau.cg.ex3.entities.scene;

import il.ac.tau.cg.ex3.entities.Entity;
import il.ac.tau.cg.ex3.math.Point;
import il.ac.tau.cg.ex3.math.Vector;

public class Camera implements Entity
{
	private Point  position;
	private Vector viewDirection;
	private Vector upDirection;
	
	private double viewPlaneWidth;
		
	public Camera(Point position, Vector viewDirection, Vector upDirection, 
				  double viewPlaneDist, double viewPlaneWidth)
	{
		super();
		
		this.position       = position;
		this.viewPlaneWidth = viewPlaneWidth;
		
		this.viewDirection  = viewDirection.normalize().scale(viewPlaneDist);
		
		if (upDirection.isOrtho(viewDirection))
		{
			this.upDirection = upDirection.normalize();
		}
		else
		{
			Vector leftDirection = upDirection.cross(viewDirection);
			
			this.upDirection = (viewDirection.cross(leftDirection)).normalize();
		}
	}

	public Camera(Point position, Point lookAt, Vector upDirection, 
			  	  double viewPlaneDistance, double viewPlaneWidth)
	{
		this(position, new Vector(position, lookAt), upDirection, viewPlaneDistance, viewPlaneWidth);
	}
	
	public Camera(Point position, Point lookAt, Vector upDirection, double viewPlaneDistance)
	{
		this(position, lookAt, upDirection, viewPlaneDistance, 2.0);
	}
	
	public Camera(Point position, Vector viewDirection, Vector upDirection, double viewPlaneDistance)
	{
		this(position, viewDirection, upDirection, viewPlaneDistance, 2.0);
	}
	
	public Point getPosition()
	{
		return position;
	}

	public void setPosition(Point position)
	{
		this.position = position;
	}

	public Vector getViewDirection()
	{
		return viewDirection;
	}

	public void setViewDirection(Vector viewDirection)
	{
		this.viewDirection = viewDirection;
	}

	public Vector getUpDirection()
	{
		return upDirection;
	}

	public void setUpDirection(Vector upDirection)
	{
		this.upDirection = upDirection;
	}

	public double getViewPlaneWidth()
	{
		return viewPlaneWidth;
	}

	public void setViewPlaneWidth(double viewPlaneWidth)
	{
		this.viewPlaneWidth = viewPlaneWidth;
	}
	
	public Point getLookAt()
	{
		return position.add(viewDirection);
	}
}
